/******************************************************************************
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * libkperf licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 * Author:
 * Create: 2025-01-13
 * Description: Thread binding main entry
 ******************************************************************************/

#include "../include/thread_binding.h"
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <signal.h>

using namespace ThreadBinding;

// 全局变量用于信号处理
static ThreadBindingManager* g_manager = nullptr;

void signal_handler(int signal) {
    if (signal == SIGINT || signal == SIGTERM) {
        std::cout << "\nReceived interrupt signal, shutting down..." << std::endl;
        if (g_manager) {
            g_manager->stop();
        }
    }
}

void print_usage() {
    std::cout << "Usage: thread_binding <process_keyword> [options]\n";
    std::cout << "Options:\n";
    std::cout << "  --interval <ms>         Data collection interval in ms (default: 100)\n";
    std::cout << "  --bind-interval <ms>    Binding update interval in ms (default: 1000)\n";
    std::cout << "  --min-collect <ms>      Minimum PMU collection time in ms (default: 100)\n";
    std::cout << "  --strategy <activity|miss|hybrid>  Binding strategy (default: activity)\n";
    std::cout << "  --no-continuous         Only bind once at start\n";
    std::cout << "  --verbose               Verbose output\n";
    std::cout << "  -h, --help              Show this help\n";
}

int main(int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    
    // 设置信号处理
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    
    ThreadBinding::Config config;
    config.process_keyword = argv[1];
    for (int i = 2; i < argc; ++i) {
        std::string arg = argv[i];
        if (arg == "--interval" && i + 1 < argc) {
            config.collection_interval_ms = std::stoull(argv[++i]);
        } else if (arg == "--bind-interval" && i + 1 < argc) {
            config.binding_interval_ms = std::stoull(argv[++i]);
        } else if (arg == "--min-collect" && i + 1 < argc) {
            config.min_collection_time_ms = std::stoull(argv[++i]);
        } else if (arg == "--strategy" && i + 1 < argc) {
            std::string strat = argv[++i];
            if (strat == "activity") config.strategy = BindingStrategy::ACTIVITY_BASED;
            else if (strat == "miss") config.strategy = BindingStrategy::MISS_RATIO_BASED;
            else if (strat == "hybrid") config.strategy = BindingStrategy::HYBRID;
        } else if (arg == "--no-continuous") {
            config.enable_continuous_binding = false;
        } else if (arg == "--verbose") {
            config.verbose = true;
        } else if (arg == "-h" || arg == "--help") {
            print_usage();
            return 0;
        }
    }
    
    ThreadBindingManager manager(config);
    g_manager = &manager;  // 设置全局指针用于信号处理
    
    if (!manager.initialize()) {
        std::cerr << "Failed to initialize thread binding manager." << std::endl;
        return 2;
    }
    
    manager.start();
    
    // 主线程等待直到Ctrl+C
    std::cout << "Thread binding started. Press Ctrl+C to exit..." << std::endl;
    while (manager.is_running()) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    
    g_manager = nullptr;  // 清除全局指针
    return 0;
} 